package com.czz.ucenter.controller;

import com.czz.common.exception.ResultCodeEnum;
import com.czz.common.vo.R;
import com.czz.ucenter.config.JwtProperties;
import com.czz.ucenter.entity.User;
import com.czz.ucenter.service.UserService;
import com.czz.ucenter.utils.JwtUtils;
import com.czz.ucenter.vo.UserInfoVo;
import com.czz.ucenter.vo.UserVo;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName: UserController
 * @Author Czz
 * @Date 2019/12/11
 * @Time 10:55
 **/

@RestController
@RequestMapping(value = "/user/users")
public class UserController {

    @Autowired
    UserService userService;

    @Autowired
    private StringRedisTemplate redisTemplate;

    static final String TOKEN_PREFIX = "user:token:";

    /**
    * @Description 检查账号是否存在
     *     * @Param [mobile]
     *     * @Return com.czz.common.vo.R
     *     * @Author Czz
     *     * @Date 2019/12/16
     *     * @Time 11:15
    **/
    @GetMapping(value = "/check/{mobile}")
    public R check(@PathVariable String mobile){
        if (StringUtils.isEmpty(mobile)){
            return R.setResult(ResultCodeEnum.INPUT_ERROR);
        }
        Boolean flag = userService.check(mobile);
        if (flag == null || !flag){
            return R.setResult(ResultCodeEnum.MOBILE_EXISTS);
        }
        return R.ok();
    }
    
    /**
    * @Description 用户注册
    * @Param [user, code]
    * @Return com.czz.common.vo.R
    * @Author Czz
    * @Date 2019/12/16
    * @Time 11:16
    **/
    @PostMapping(value = "/register")
    public R register(User user, String code){
        if (StringUtils.isEmpty(user.getMobile()) || StringUtils.isEmpty(user.getPassword()) || StringUtils.isEmpty(user.getEmail())){
            return R.setResult(ResultCodeEnum.INPUT_ERROR);
        }
        Boolean flag = userService.register(user,code);
        if (flag == null || !flag){
            return R.error().message("注册失败，请检查注册信息！");
        }
        return R.ok();
    }

    /**
    * @Description 用户登录
    * @Param [username, password, request, response]
    * @Return com.czz.common.vo.R
    * @Author Czz
    * @Date 2019/12/16
    * @Time 16:36
    **/
    @PostMapping(value = "/login")
    public R login(
            @RequestParam String username,
            @RequestParam String password,
            HttpServletRequest request,
            HttpServletResponse response){

        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)){
            return R.setResult(ResultCodeEnum.INPUT_ERROR);
        }

        User user = userService.login(username,password,false);
        if (ObjectUtils.isEmpty(user)){
            return R.setResult(ResultCodeEnum.USERNAME_OR_PASSWORD_ERROR);
        }

        String token = JwtUtils.generateJWT(user);
        //存入cookies,token和cookies有效期都为60分钟
        //CookieUtils.setCookie(request,response, JwtProperties.NAME,token,JwtProperties.USEREXPIRE*60,null,false);

        //token存入redis，用户过期时间720分钟，12小时
        this.redisTemplate.opsForValue().set(TOKEN_PREFIX + user.getId(), token, JwtProperties.USEREXPIRE, TimeUnit.MINUTES);
        return R.ok().data("token",token);
    }
    
    /**
    * @Description 根据token解析用户信息
    * @Param [token]
    * @Return com.czz.common.vo.R
    * @Author Czz
    * @Date 2019/12/24
    * @Time 10:50
    **/
    @GetMapping(value = "/verify")
    public R getAdminInfoByJwt(HttpServletRequest request){
        String token = request.getHeader("USER-TOKEN");

        if (StringUtils.isEmpty(token)){
            return R.setResult(ResultCodeEnum.UNAUTHORIZED);
        }

        Claims claims = JwtUtils.checkJWT(token);
        String id = (String) claims.get("id");
        String mobile = (String) claims.get("mobile");
        String name = (String) claims.get("name");
        String avatar = (String) claims.get("avatar");

        UserInfoVo userInfoVo = new UserInfoVo();
        userInfoVo.setId(id);
        userInfoVo.setMobile(mobile);
        userInfoVo.setNickname(name);
        userInfoVo.setAvatar(avatar);

        String redisToken = this.redisTemplate.opsForValue().get(TOKEN_PREFIX + id);

        if (ObjectUtils.isEmpty(userInfoVo) || StringUtils.isEmpty(redisToken) || !token.equals(redisToken)){
            return R.setResult(ResultCodeEnum.UNAUTHORIZED);
        }
        return R.ok().data("userInfo",userInfoVo);
    }

    /**
    * @Description 根据id查询用户
    * @Param [id]
    * @Return com.czz.common.vo.R
    * @Author Czz
    * @Date 2020/2/11
    * @Time 16:39
    **/
    @GetMapping(value = "{id}")
    public R getUserById(@PathVariable String id){
        if (StringUtils.isEmpty(id)){
            return R.setResult(ResultCodeEnum.INPUT_ERROR);
        }
        UserVo userVo = userService.getUserById(id);
        return R.ok().data("item",userVo);
    }

    /**
     * @Description 用户更新头像
     * @Param [user]
     * @Return com.czz.common.vo.R
     * @Author Czz
     * @Date 2020/2/16
     * @Time 10:47
     **/
    @PutMapping(value = "/avatar")
    public R updateUserAvatar(User user){
        if (StringUtils.isEmpty(user.getId()) || StringUtils.isEmpty(user.getAvatar())){
            return R.setResult(ResultCodeEnum.INPUT_ERROR);
        }
        userService.updateById(user);
        //刷新token
        User temp = userService.getById(user.getId());
        String token = JwtUtils.generateJWT(temp);
        //token存入redis，用户过期时间720分钟，12小时
        this.redisTemplate.opsForValue().set(TOKEN_PREFIX + temp.getId(), token, JwtProperties.USEREXPIRE, TimeUnit.MINUTES);
        return R.ok().data("token",token);
    }

    /**
     * @Description 用户取消上传头像，删除OSS中文件
     * @Param [user]
     * @Return com.czz.common.vo.R
     * @Author Czz
     * @Date 2020/2/16
     * @Time 10:48
     **/
    @PutMapping(value = "/avatar/cancel")
    public R cancelUpdateUserAvatar(User user){
        if (StringUtils.isEmpty(user.getId()) || StringUtils.isEmpty(user.getAvatar())){
            return R.setResult(ResultCodeEnum.INPUT_ERROR);
        }
        userService.cancelAvatarUpload(user.getAvatar());
        return R.ok();
    }

    /**
    * @Description 发送短信验证码
    * @Param [phone]
    * @Return com.czz.common.vo.R
    * @Author Czz
    * @Date 2020/2/20
    * @Time 13:30
    **/
    @PostMapping(value = "/sms")
    public R sendVerifyCode(String mobile){
        if (StringUtils.isEmpty(mobile)){
            return R.setResult(ResultCodeEnum.INPUT_ERROR);
        }
        userService.sendVerifyCode(mobile);
        return R.ok();
    }

    /**
    * @Description 检验验证码是否有效
    * @Param [phone]
    * @Return com.czz.common.vo.R
    * @Author Czz
    * @Date 2020/2/21
    * @Time 10:55
    **/
    @GetMapping(value = "/sms/{phone}/{code}")
    public R checkCode(@PathVariable String phone,@PathVariable String code){
        if (StringUtils.isEmpty(phone) || StringUtils.isEmpty(code)){
            return R.setResult(ResultCodeEnum.INPUT_ERROR);
        }
        Integer flag = userService.checkCode(phone,code);
        if (flag.equals(0)) return R.ok();
        if (flag.equals(1)) return R.error().message("验证码过期，请刷新验证码");
        return R.error().message("验证码输入错误，请重新输入");
    }

    /**
    * @Description 修改用户密码
    * @Param [id, ordPassword, newPassword]
    * @Return com.czz.common.vo.R
    * @Author Czz
    * @Date 2020/2/21
    * @Time 18:35
    **/
    @PutMapping(value = "{id}")
    public R updatePassword(@PathVariable String id,String oldPassword,String newPassword){
        if (StringUtils.isEmpty(id) || StringUtils.isEmpty(oldPassword) || StringUtils.isEmpty(newPassword)){
            return R.setResult(ResultCodeEnum.INPUT_ERROR);
        }
        userService.updatePassword(id,oldPassword,newPassword);
        return R.ok();
    }

    /**
    * @Description 修改用户信息
    * @Param [id, user]
    * @Return com.czz.common.vo.R
    * @Author Czz
    * @Date 2020/2/22
    * @Time 10:28
    **/
    @PutMapping(value = "/info/{id}")
    public R updateUserById(@PathVariable String id,User user){
        if (StringUtils.isEmpty(id) || ObjectUtils.isEmpty(user)){
            return R.setResult(ResultCodeEnum.INPUT_ERROR);
        }
        user.setId(id);
        userService.updateUserById(user);
        return R.ok();
    }

    /**
    * @Description 用户注销
    * @Param [userId]
    * @Return com.czz.common.vo.R
    * @Author Czz
    * @Date 2020/3/21
    * @Time 13:40
    **/
    @PostMapping(value = "/logout")
    public R logout(String userId){
        if (StringUtils.isEmpty(userId)){
            return R.setResult(ResultCodeEnum.INPUT_ERROR);
        }
        //删除redis中token
        this.redisTemplate.delete(TOKEN_PREFIX + userId);
        return R.ok();
    }
}
